<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
  <meta http-equiv="Content-Style-Type" content="text/css" />
  <meta name="generator" content="pandoc" />
  <title>Linux 内核开发</title>
  <style type="text/css">code{white-space: pre;}</style>
  <style type="text/css">
div.sourceCode { overflow-x: auto; }
table.sourceCode, tr.sourceCode, td.lineNumbers, td.sourceCode {
  margin: 0; padding: 0; vertical-align: baseline; border: none; }
table.sourceCode { width: 100%; line-height: 100%; }
td.lineNumbers { text-align: right; padding-right: 4px; padding-left: 4px; color: #aaaaaa; border-right: 1px solid #aaaaaa; }
td.sourceCode { padding-left: 5px; }
code > span.kw { color: #007020; font-weight: bold; } /* Keyword */
code > span.dt { color: #902000; } /* DataType */
code > span.dv { color: #40a070; } /* DecVal */
code > span.bn { color: #40a070; } /* BaseN */
code > span.fl { color: #40a070; } /* Float */
code > span.ch { color: #4070a0; } /* Char */
code > span.st { color: #4070a0; } /* String */
code > span.co { color: #60a0b0; font-style: italic; } /* Comment */
code > span.ot { color: #007020; } /* Other */
code > span.al { color: #ff0000; font-weight: bold; } /* Alert */
code > span.fu { color: #06287e; } /* Function */
code > span.er { color: #ff0000; font-weight: bold; } /* Error */
code > span.wa { color: #60a0b0; font-weight: bold; font-style: italic; } /* Warning */
code > span.cn { color: #880000; } /* Constant */
code > span.sc { color: #4070a0; } /* SpecialChar */
code > span.vs { color: #4070a0; } /* VerbatimString */
code > span.ss { color: #bb6688; } /* SpecialString */
code > span.im { } /* Import */
code > span.va { color: #19177c; } /* Variable */
code > span.cf { color: #007020; font-weight: bold; } /* ControlFlow */
code > span.op { color: #666666; } /* Operator */
code > span.bu { } /* BuiltIn */
code > span.ex { } /* Extension */
code > span.pp { color: #bc7a00; } /* Preprocessor */
code > span.at { color: #7d9029; } /* Attribute */
code > span.do { color: #ba2121; font-style: italic; } /* Documentation */
code > span.an { color: #60a0b0; font-weight: bold; font-style: italic; } /* Annotation */
code > span.cv { color: #60a0b0; font-weight: bold; font-style: italic; } /* CommentVar */
code > span.in { color: #60a0b0; font-weight: bold; font-style: italic; } /* Information */
  </style>
  <link rel="stylesheet" href="doc/linux-style.css" type="text/css" />
</head>
<body>
<div id="header">
<h1 class="title">Linux 内核开发</h1>
</div>
<div id="TOC">
<ul>
<li><a href="#linux-内核开发">Linux 内核开发</a><ul>
<li><a href="#一环境配置">一、环境配置</a></li>
<li><a href="#二gdb调试">二、GDB调试</a></li>
<li><a href="#三常用命令工具必须掌握">三、常用命令/工具(必须掌握)</a></li>
<li><a href="#四个人博客搭建">四、个人博客搭建</a></li>
<li><a href="#内核源码解读">内核源码解读</a></li>
<li><a href="#文件系统">文件系统</a></li>
<li><a href="#内存管理">内存管理</a></li>
<li><a href="#进程线程管理与调度">进程、线程管理与调度</a></li>
<li><a href="#内核调试工具">内核调试工具</a></li>
<li><a href="#linux-内核实战">Linux 内核实战</a></li>
</ul></li>
</ul>
</div>
<h1 id="linux-内核开发">Linux 内核开发</h1>
<h2 id="一环境配置">一、环境配置</h2>
<p>首先肯定要先用虚拟机起一个linux操作系统，我用的是Ubuntu22.04发行版。</p>
<h3 id="ssh远程登陆">1.ssh远程登陆</h3>
<p>使用远程登陆的方法就可以在物理机器上远程操作了,复制粘贴什么的也特别方便;</p>
<p>还有一个需要注意的地方是远程的时候,一定要使用tmux创建一个新的会话,这样网络断了,你的进程不会丢失。</p>
<p>关于tmux的一些使用可以看我后面的记录。</p>
<p><strong>Windows/Linux → 物理服务器 → Docker容器 → QEMU虚拟机</strong></p>
<div class="sourceCode"><pre class="sourceCode sh"><code class="sourceCode bash"><span class="fu">ssh</span> 账号@193.x.x.x
<span class="fu">ssh</span> 账号@172.x.x.x
<span class="bu">exit</span>    #退出</code></pre></div>
<p>配置 SSH 免密登录到 Docker 容器：<code>ssh-copy-id root@xxx.xxx.xxx.xxx</code> 若报错（如密钥不存在），先执行 ssh-keygen。</p>
<p>为什么要这么麻烦，从物理机起一个虚拟机后在用一个qemu起一个？</p>
<p>首先我们去测试和分析内核代码的时候，肯定要针对不同的内核版本分析，用qemu可以很好的去启动不同的内核版本。</p>
<p>如果内核源码在qemu内部启动，镜像坏了或在内核错误了，可以重新再拉一个内核和镜像。</p>
<h3 id="安装-code-server">安装 code-server</h3>
<p><code>curl -fsSL https://code-server.dev/install.sh | sh</code></p>
<h3 id="生成代码索引">生成代码索引</h3>
<p><code>make gtags  # 用于 VSCode 的代码跳转功能</code></p>
<p>安装这两个主要想着方便我用类似VScode的形式去查看内核源码</p>
<p>当然也可以用vim去查看内核，后面将vim的使用的时候也有具体的操作，我对vim接触太少了我还是用不太习惯。</p>
<h3 id="内核编译">2.内核编译</h3>
<p>首先需要下载内核源码，<a href="https://www.kernel.org/pub/linux/kernel/">内核源码的地址</a>，这个地址里面有各个版本的内核源码。</p>
<p>我用到的是内核4.19版本的源码，然后创建好的虚拟机编译去内核源码。</p>
<h4 id="先建立专用编译目录">先建立专用编译目录</h4>
<p><code>cd llinux-4.9.19/</code> <code>mkdir build</code></p>
<h4 id="配置内核选项">配置内核选项</h4>
<p><code>make O=build menuconfig</code></p>
<h4 id="编译内核镜像">编译内核镜像</h4>
<p><code>make O=build bzImage -j$(nproc)</code></p>
<h4 id="make内容补充">make内容补充</h4>
<p>可以使用<code>make help | less</code>查看<code>make</code>命令的具体内容</p>
<div class="sourceCode"><pre class="sourceCode sh"><code class="sourceCode bash"><span class="co">#清理环境相关</span>
<span class="fu">make</span> mrproper           #清理环境 彻底清理所有生成文件、配置文件及备份文件（需重新配置内核）
<span class="fu">make</span> distclean          #在 mrproper 基础上，额外删除编辑器备份和补丁文件（完全干净的环境）

<span class="co">#配置内核相关</span>
<span class="fu">make</span> defconfig          # 生成默认配置
<span class="fu">make</span> menuconfig         # 自定义调整配置
<span class="fu">make</span> xconfig / make gconfig <span class="co">#分别使用 Qt 或 GTK+ 图形界面配置内核（适合桌面环境）</span>
<span class="fu">make</span> localmodconfig     #根据当前加载的模块生成精简配置（禁用未使用的模块）
<span class="fu">make</span> allyesconfig       #将所有选项设置为 yes（生成最大化的内核，用于测试
<span class="fu">make</span> allnoconfig        #将所有选项设置为 no（最小化内核，需手动启用功能）
<span class="fu">make</span> testconfig         #运行 Kconfig 的单元测试
<span class="fu">make</span> debug.config       # 将 debug.config 合并到当前 .config 文件
<span class="fu">make</span> x86_debug.config       #针对 x86/x86_64 架构的 调试和测试选项
<span class="fu">make</span> kvm_guest.config       #优化内核配置以作为 KVM 虚拟机客户机（Guest OS） 运行

<span class="co">#编译内核与模块</span>
<span class="fu">make</span> vmlinux        #编译生成内核的裸二进制文件（未压缩的内核镜像）
<span class="fu">make</span> modules_install    #将编译好的模块安装到 /lib/modules/<span class="va">$(</span><span class="fu">uname</span> -r<span class="va">)</span>/ 目录
<span class="fu">make</span> headers_install    #安装内核头文件到 ./usr（用于开发用户空间程序）</code></pre></div>
<h4 id="模块独立编译">模块独立编译</h4>
<h5 id="修改makefie文件">修改makefie文件</h5>
<p><code>CONFIG_EXT2_FS := m  # 设置为模块编译</code></p>
<h5 id="执行编译">执行编译</h5>
<p><code>make -C /path/to/kernel/source M=$(pwd) modules</code></p>
<h3 id="qemu启动内核">3.qemu启动内核</h3>
<p>内核编译好了之后，就需要用一个仿真器启动内核了，如何安装qemu和配置qemu的启动选项是最重要的。</p>
<p><strong>qemu安装参考：</strong><a href="https://www.qemu.org/download/#linux">qemu官网</a></p>
<p>也可以下载qemu源码进行安装： 先安装qemu所需的依赖软件</p>
<div class="sourceCode"><pre class="sourceCode sh"><code class="sourceCode bash"><span class="co"># ubuntu 22.04</span>
<span class="fu">sudo</span> apt-get install libattr1-dev libcap-ng-dev -y
<span class="fu">sudo</span> apt install ninja-build -y
<span class="fu">sudo</span> apt-get install libglib2.0-dev -y
<span class="fu">sudo</span> apt-get install libpixman-1-dev -y
<span class="fu">sudo</span> apt install python3-pip
<span class="ex">pip</span> install tomli</code></pre></div>
<p>然后再下载qemu源码，编译安装</p>
<div class="sourceCode"><pre class="sourceCode sh"><code class="sourceCode bash"><span class="fu">git</span> clone https://gitlab.com/qemu-project/qemu.git <span class="co">#从git上获取qemu源码</span>
<span class="bu">cd</span> qemu
<span class="fu">git</span> submodule init  #初始化git子模块
<span class="fu">git</span> submodule update --recursive <span class="co">#更新git子模块</span>
<span class="fu">mkdir</span> build
<span class="bu">cd</span> build/
<span class="ex">../configure</span> --enable-kvm --enable-virtfs --prefix=<span class="va">${HOME}</span>/dingpenglong/sw/qemu/ <span class="co">#--启用kvm硬件虚拟化加速--启用Virfs支持 --指定安装路径</span>
<span class="fu">make</span> -j<span class="kw">`</span><span class="ex">nproc</span><span class="kw">`</span>
<span class="fu">make</span> install</code></pre></div>
<p>完成这些还不够，还需要解开qemu的一些权限，以方便我们启动qemu： - qemu-bridge-helper</p>
<div class="sourceCode"><pre class="sourceCode sh"><code class="sourceCode bash"><span class="co"># 源码安装的</span>
<span class="fu">sudo</span> chown root libexec/qemu-bridge-helper <span class="co">#将文件所有者改为root</span>
<span class="fu">sudo</span> chmod u+s libexec/qemu-bridge-helper  #设置setuid
<span class="co"># apt安装的</span>
<span class="fu">sudo</span> chown root /usr/lib/qemu/qemu-bridge-helper
<span class="fu">sudo</span> chmod u+s /usr/lib/qemu/qemu-bridge-helper</code></pre></div>
<ul>
<li>kvm</li>
</ul>
<div class="sourceCode"><pre class="sourceCode sh"><code class="sourceCode bash"><span class="fu">groups</span> <span class="kw">|</span> <span class="fu">grep</span> kvm   #检查当前用户是否在kvm组里面
<span class="fu">sudo</span> usermod -aG kvm <span class="va">$USER</span>  #将当前用户加入 kvm 组
<span class="fu">su</span> - <span class="va">$USER</span> <span class="co"># 或退出shell重新登录, 但在tmux中不起作用，tmux需要执行newgrp kvm</span></code></pre></div>
<ul>
<li>网络桥接策略</li>
</ul>
<div class="sourceCode"><pre class="sourceCode sh"><code class="sourceCode bash"><span class="co"># 源码安装的 QEMU</span>
<span class="fu">mkdir</span> -p etc/qemu
<span class="ex">vim</span> etc/qemu/bridge.conf   # 添加内容：allow virbr0

<span class="co"># apt 安装的 QEMU</span>
<span class="fu">sudo</span> mkdir -p /etc/qemu/
<span class="fu">sudo</span> vim /etc/qemu/bridge.conf  # 添加内容：allow virbr0</code></pre></div>
<ul>
<li>自定义虚拟机网段</li>
</ul>
<div class="sourceCode"><pre class="sourceCode sh"><code class="sourceCode bash"><span class="ex">virsh</span> net-list                   # 查看虚拟网络列表
<span class="ex">virsh</span> net-edit default           # 编辑名为 <span class="st">&quot;default&quot;</span> 的网络配置
<span class="co"># 在 XML 中修改 &lt;ip&gt; 段，例如：</span>
<span class="co"># &lt;ip address=&#39;192.168.100.1&#39; netmask=&#39;255.255.255.0&#39;&gt;</span>
<span class="co">#   &lt;dhcp&gt;</span>
<span class="co">#     &lt;range start=&#39;192.168.100.2&#39; end=&#39;192.168.100.254&#39;/&gt;</span>
<span class="co">#   &lt;/dhcp&gt;</span>
<span class="co"># &lt;/ip&gt;</span>

<span class="ex">virsh</span> net-destroy default        # 停止当前网络
<span class="ex">virsh</span> net-start default          # 用新配置启动网络</code></pre></div>
<p>安装和配置完成之后呢，就需要知道如何启动qemu了，启动配置的参数也很重要，可以把启动命令编写成一个shell脚本。</p>
<p><code>vim start.sh</code>编辑内容</p>
<div class="sourceCode"><pre class="sourceCode sh"><code class="sourceCode bash"><span class="va">kernel_version=</span>stable  # 设置内核版本变量为<span class="st">&quot;stable&quot;</span>

<span class="ex">qemu-system-x86_64</span> <span class="dt">\ </span>  # 启动x86_64架构的虚拟机
<span class="ex">-enable-kvm</span> <span class="dt">\ </span>         # 启用KVM硬件虚拟化加速
<span class="ex">-cpu</span> host <span class="dt">\ </span>           # 使用宿主机CPU的所有特性
<span class="ex">-smp</span> 16 <span class="dt">\ </span>             # 分配16个CPU核心给虚拟机
<span class="ex">-m</span> 4096 <span class="dt">\ </span>             # 分配4096MB(4GB)内存给虚拟机
<span class="ex">-kernel</span> /home/dingpenglong/code/<span class="va">$kernel_version</span>/x86_64-build/arch/x86_build/boot/bzImage <span class="dt">\ </span> <span class="co"># 指定自定义内核镜像路径</span>
<span class="ex">-virtfs</span> local,id=kmod_dev,path=/home/dingpenglong/,readonly,mount_tag=9p,security_model=none <span class="dt">\ </span> <span class="co"># 共享宿主机目录作为9p只读文件系统</span>
<span class="ex">-vga</span> none <span class="dt">\ </span>           # 禁用虚拟显卡输出
<span class="ex">-nographic</span> <span class="dt">\ </span>          # 完全禁用图形界面，输出重定向到当前终端
<span class="ex">-append</span> <span class="st">&quot;nokaslr console=ttyS0 root=/dev/vda rw kmemleak=on&quot;</span> <span class="dt">\ </span> <span class="co"># 内核启动参数：禁用地址随机化、串口控制台、根设备可读写、启用内存泄漏检测</span>
<span class="ex">-device</span> virtio-scsi-pci <span class="dt">\ </span> <span class="co"># 添加virtio-scsi控制器设备</span>
<span class="ex">-drive</span> file=image.qcow2,if=none,format=qcow2,cache=writeback,file.locking=off,id=root <span class="dt">\ </span> <span class="co"># 定义qcow2格式的根磁盘镜像</span>
<span class="ex">-device</span> virtio-blk,drive=root,id=d_root <span class="dt">\ </span> <span class="co"># 将根磁盘作为virtio块设备挂载</span>
<span class="ex">-net</span> tap <span class="dt">\ </span>            # 使用TAP模式连接宿主机网络
<span class="ex">-net</span> nic,model=virtio,macaddr=00:11:22:33:44:03 <span class="dt">\ </span> <span class="co"># 添加virtio网卡并指定MAC地址</span>
<span class="ex">-drive</span> file=1,if=none,format=raw,cache=writeback,file.locking=off,id=dd_1 <span class="dt">\ </span> <span class="co"># 定义原始格式(raw)的附加磁盘</span>
<span class="ex">-device</span> scsi-hd,drive=dd_1,id=disk_1,logical_block_size=512,physical_block_size=512 <span class="dt">\ </span> <span class="co"># 将附加磁盘作为SCSI硬盘挂载</span>
<span class="ex">-gdb</span> tcp::5555        # 开启GDB调试服务，监听5553端口</code></pre></div>
<p>在每次启动qemu'虚拟机的时候，可以先使用<code>ps -e -o pid,ppid,args | grep qemu</code></p>
<p>先查看有没有多个虚拟机开启，可以看到，三个进程都是开启的 qenu-system-x86_64</p>
<p>输出的父子进程关系如下所示： <code>5601 → 5602 (sudo) → 5603 (sudo) → 5604 (qenu-system-x86_64)</code></p>
<p><strong>qemu启动后的三种杀死方式</strong> 1. 终端快捷键：Ctrl + A 然后按 X。 2. 按快捷键ctrl+a c（先按ctrl+a松开后再按c）再输入quit强制退出qemu。 3. 找到qemu的进程 执行<code>sudo kill -9 &lt;进程号&gt;</code>。</p>
<h2 id="二gdb调试">二、GDB调试</h2>
<p>GDB调试qemu,GDB调试需要去调试内核源码build/vmlinux,至于为什么是这个文件?</p>
<p>我查了一些内容:vmlinux 是编译生成的 未压缩、带完整调试符号的 ELF 可执行文件，也就是说vmlinux是完整的内核数据库,bzImage则是压缩过的。</p>
<div class="sourceCode"><pre class="sourceCode sh"><code class="sourceCode bash"><span class="co">#基础调试</span>
<span class="ex">target</span> remote:5555          #你的调试器（GDB）连接到那台<span class="st">&quot;远程电脑&quot;</span>，让 GDB 可以控制它的执行
<span class="ex">target</span> remote :1234             # 连接 QEMU 调试端口
<span class="ex">c</span>                               # 继续执行 (Continue)
<span class="ex">Ctrl+C</span>                           # 中断程序执行
<span class="ex">si</span>                              # 单步执行汇编指令 (Step Instruction)
<span class="ex">n</span>                               # 源代码级单步跳过 (Next)
<span class="ex">s</span>                               # 源代码级单步进入 (Step)

<span class="co">#断点调试</span>
<span class="ex">b</span> start_kernel              # 在函数入口设置断点
<span class="ex">b</span> *0xffffffff81000000           # 在指定地址设置断点
<span class="ex">watch</span> *(int*)<span class="ex">0x1234</span>         # 监控内存地址写入
<span class="ex">rwatch</span> [expression]         # 监控内存读取
<span class="ex">info</span> breakpoints            # 查看所有断点
<span class="ex">disable</span> 2               # 禁用 2 号断点
<span class="ex">delete</span> 3                # 删除 3 号断点

<span class="co">#上下文查看</span>
<span class="ex">bt</span>                  # 查看调用栈 (BackTrace)
<span class="ex">info</span> registers              # 显示所有寄存器值
<span class="ex">p</span> <span class="va">$rax</span>                  # 查看 RAX 寄存器值
<span class="ex">p</span> <span class="va">$lx_current</span>()<span class="ex">.pid</span>         #打印断点的进程
<span class="ex">p</span> <span class="va">$lx_current</span>()<span class="ex">.comm</span>            #打印断点的进程
<span class="kw">&amp;((</span>struct cifsFileInfo *)0)-&gt;tlink  #打印结构体偏移量

<span class="co">#内存操作</span>
x/10x 0x1234                # 以十六进制查看 10 个内存字
x/20s 0xabcd                # 查看内存中的 ASCII 字符串
x/i <span class="va">$pc</span>                 # 反汇编当前指令
disassemble /r              # 带机器码反汇编当前函数
set <span class="dt">{int}</span>0x1234 = 5         # 修改内存值</code></pre></div>
<h2 id="三常用命令工具必须掌握">三、常用命令/工具(必须掌握)</h2>
<p><a href="https://linuxcommand.p2hp.com/">Linux命令大全</a></p>
<div class="sourceCode"><pre class="sourceCode sh"><code class="sourceCode bash"><span class="fu">tar</span> -xzf filename.tar.gz  # 对于.tar.gz文件
<span class="fu">tar</span> -xJf filename.tar.xz  # 对于.tar.xz文件
<span class="fu">sudo</span> apt install ./filename.deb  #对于安装deb文件</code></pre></div>
<h3 id="vim编辑器">1.vim编辑器</h3>
<h4 id="点击查看vim的使用"><a href="https://dingpenglong.com/tools/vim">点击查看vim的使用</a></h4>
<h3 id="git的使用">2.Git的使用</h3>
<h4 id="点击查看git的使用"><a href="https://dingpenglong.com/tools/git">点击查看git的使用</a></h4>
<h3 id="tmux终端复用">3.Tmux终端复用</h3>
<div class="sourceCode"><pre class="sourceCode sh"><code class="sourceCode bash"><span class="ex">tmux</span> new -t <span class="op">&lt;</span>name<span class="op">&gt;</span>  #创建名为 <span class="op">&lt;</span>name<span class="op">&gt;</span> 的新会话
<span class="ex">Ctrl</span> + B D      #退出当前会话
<span class="ex">tmux</span> det   #退出当前tmux到后台
<span class="ex">tmux</span> ls         #显示所有会话tm
<span class="ex">tmux</span> attach -t <span class="op">&lt;</span>name<span class="op">&gt;</span>   #重新连接到指定会话
<span class="ex">tmux</span> kill-session -t  <span class="op">&lt;</span>name<span class="op">&gt;</span> <span class="co">#删除会话</span></code></pre></div>
<h3 id="ps进程管理">4.ps进程管理</h3>
<div class="sourceCode"><pre class="sourceCode sh"><code class="sourceCode bash"><span class="fu">ps</span> aux          #查看所有进程的详细信息    
<span class="fu">ps</span> -eo pid,ppid,cmd <span class="co">#显示进程的 PID、PPID 和完整命令   </span>
<span class="fu">ps</span> -ef <span class="kw">|</span> <span class="fu">grep</span> <span class="op">&lt;</span>进程名<span class="op">&gt;</span> <span class="co">#过滤特定进程 ps -ef | grep nginx</span>
<span class="fu">ps</span> -e -o pid,ppid,args <span class="kw">|</span> <span class="fu">grep</span> qemu    #用于查询qemu虚拟机的pid、ppid、args 每次启动qemu虚拟机的时候要确保没有同时开启多个虚拟机</code></pre></div>
<h3 id="sshscp远程连接">5.SSH&amp;SCP远程连接</h3>
<div class="sourceCode"><pre class="sourceCode sh"><code class="sourceCode bash"><span class="fu">ssh</span> user@host               #例如ssh root@192.168.1.100
<span class="fu">ssh</span> -p <span class="op">&lt;</span>port<span class="op">&gt;</span> user@host         #指定端口登录
<span class="fu">scp</span> file user@host:/path        #上传文件到远程主机
<span class="fu">scp</span> user@host:/path/file local_dir  #从远程主机下载文件
<span class="ex">ssh-copy-id</span> user@host           #将公钥复制到远程主机,在远程登陆的时候可以先将远程的主机公钥复制过来，实现免密登陆</code></pre></div>
<h2 id="四个人博客搭建">四、个人博客搭建</h2>
<p>博客怎么搭建大致流程就是如下：</p>
<p>写博客有个好处就算可以让自己做过的东西再梳理一遍，这样更有效的加深记忆。</p>
<h3 id="域名配置流程">域名配置流程</h3>
<ol style="list-style-type: decimal">
<li>阿里云注册<code>yourname.com</code></li>
<li>添加 DNS 解析记录</li>
</ol>
<div class="sourceCode"><pre class="sourceCode sh"><code class="sourceCode bash"><span class="ex">GitHub</span> Pages 的 IP 地址： 185.199.108.153 185.199.109.153 185.199.110.153 185.199.111.153</code></pre></div>
<ol start="3" style="list-style-type: decimal">
<li>GitHubPages 配置</li>
</ol>
<div class="sourceCode"><pre class="sourceCode sh"><code class="sourceCode bash">创建 <span class="op">&lt;</span><span class="ex">username</span><span class="op">&gt;</span>.github.io 仓库
启用 <span class="ex">GitHub</span> Pages 服务
配置自定义域名</code></pre></div>
<ol start="4" style="list-style-type: decimal">
<li>使用<code>pandoc</code>将markdown文件生成类似Linux源码格式的html文件</li>
</ol>
<div class="sourceCode"><pre class="sourceCode sh"><code class="sourceCode bash"><span class="co"># 下载Linux内核官方CSS</span>
<span class="fu">wget</span> https://kernel.org/doc/html/latest/_static/css/theme.css
<span class="ex">pandoc</span> input.md -o output.html --css=theme.css --toc --standalone</code></pre></div>
<h2 id="内核源码解读">内核源码解读</h2>
<h3 id="点击查看linux内核源码解读持续更新中"><a href="https://dingpenglong.com/linux_kernel/code/linux_kernel_codestudy">点击查看Linux内核源码解读(持续更新中)</a></h3>
<h2 id="文件系统">文件系统</h2>
<h3 id="点击查看文件系统"><a href="https://dingpenglong.com/linux_kernel/fs/fs">点击查看文件系统</a></h3>
<h2 id="内存管理">内存管理</h2>
<h3 id="点击查看内存管理"><a href="https://dingpenglong.com/linux_kernel/mm/mm">点击查看内存管理</a></h3>
<h2 id="进程线程管理与调度">进程、线程管理与调度</h2>
<h3 id="点击查看进程线程管理与调度"><a href="https://dingpenglong.com/linux_kernel/process/process">点击查看进程、线程管理与调度</a></h3>
<h2 id="内核调试工具">内核调试工具</h2>
<h3 id="点击查看内核调试工具"><a href="https://dingpenglong.com/linux_kernel/kernel/linux_kernel_debug">点击查看内核调试工具</a></h3>
<h2 id="linux-内核实战">Linux 内核实战</h2>
<h3 id="点击查看nfs实战问题分析持续更新中"><a href="https://dingpenglong.com/linux_kernel/fs/nfs/issue/linux_kernel_nfs_problem">点击查看nfs实战问题分析(持续更新中)</a></h3>
<h3 id="遇到的常见问题的小tips">遇到的常见问题的小Tips</h3>
<h4 id="虚拟机卡在了boot-form-hard-disk阶段">1. 虚拟机卡在了Boot form Hard Disk阶段</h4>
<p>这种情况只能重装虚拟机系统<br />
注：做实验千万不要在Vitrual manager的虚拟机上跑，最好在qemu上跑。</p>
<h4 id="调试补丁">2. 调试补丁</h4>
<ul>
<li>应用补丁： 确保你的工作目录是你的Linux内核源代码根目录，patch命令应用补丁<br />
<code>patch -p1 &lt; /home/linux/blog/course/kernel/src/0001-debug-vfs.patch</code></li>
<li>然后配置内核<code>make menuconfig</code>、编译内核<code>make bzImage -j8</code></li>
</ul>
<h4 id="git-clone时候failed-to-connect-to-github.com-port-443-after-0-ms-连接被拒绝">3.git clone时候：Failed to connect to github.com port 443 after 0 ms: 连接被拒绝</h4>
<ul>
<li><ol style="list-style-type: decimal">
<li>如果在学校和公司无法在网站上访问，可以申请一个服务器代理。</li>
</ol></li>
<li><ol start="2" style="list-style-type: decimal">
<li>检查防火墙配置。<code>sudo systemctl disable firewalld</code></li>
</ol></li>
</ul>
<h4 id="编译的.ko文件如何映射到内核文件里面">4.编译的.ko文件，如何映射到内核文件里面？</h4>
<ul>
<li><ol style="list-style-type: decimal">
<li>加载内核模块:<code>sudo insmod your_module.ko</code> 或者<code>sudo modprobe your_module</code></li>
</ol></li>
<li><ol start="2" style="list-style-type: decimal">
<li>验证是否加载成功：<code>lsmod | grep your_module</code></li>
</ol></li>
<li><ol start="3" style="list-style-type: decimal">
<li>卸载模块：<code>sudo rmmod your_module</code></li>
</ol></li>
</ul>
<h4 id="遇到无法卸载挂载文件">5.遇到无法卸载挂载文件？</h4>
<ul>
<li><p>有时候umount挂载文件会出现'device is busy'的问题</p></li>
<li><p>可以使用以下命令查看使用挂载点的进程: <code>lsof +D &lt;挂载点&gt;</code> <code>fuser -m &lt;挂载点&gt;</code> 找到进程号后，就可以使用<code>kill -SIGKILL &lt;进程号&gt;</code> 杀死进程</p></li>
</ul>
<h4 id="mount-使用nfs3.0版本无法挂载的问题">6.mount 使用nfs3.0版本无法挂载的问题？</h4>
<ul>
<li>需要使用绝对路径 <code>mount -t nfs -o vers=3 ${server_ip}:/tmp/s_test /mnt</code></li>
</ul>
<h4 id="从源码安装bochs的时候报错-出现错误install-cannot-stat-.bochsdbg-no-such-file-or-directory">7.从源码安装bochs的时候报错 出现错误”install: cannot stat `./bochsdbg': No such file or directory“？</h4>
<ul>
<li>将源文件中bochs的文件夹名称改为bochsdbg即可。</li>
</ul>
<h4 id="在使用ssh登陆的时候可以修改etcsshssh_config">8.在使用ssh登陆的时候可以，修改/etc/ssh/ssh_config</h4>
<ul>
<li>GSSAPIAuthentication no 前面的#去掉，SH 客户端将不会尝试使用 GSSAPI 进行认证。</li>
</ul>
</body>
</html>
